-- drop function if exists sm_sc.fv_mx_ele_2d_2_3d(anyarray, int, int);
create or replace function sm_sc.fv_mx_ele_2d_2_3d
(
  i_array_2d      anyarray      ,
  i_cnt_per_grp   int           ,       -- 升维的新增维度的维度长度(元素个数)。如果 i_dim_pin = 1 则，新增维度为3；如果 i_dim_pin = 2 则，新增维度为2。
  i_dim_pin       int                   -- 定住的维度，1 或 2
)
returns anyarray
as
$$
-- declare

begin
  if array_ndims(i_array_2d) <> 2
  then 
    raise exception 'ndims should be 2.';
  end if;
  
  if array_length(i_array_2d, case i_dim_pin when 1 then 2 when 2 then 1 end) % i_cnt_per_grp > 0
    or i_cnt_per_grp not between 1 and array_length(i_array_2d, case i_dim_pin when 1 then 2 when 2 then 1 end)
  then 
    raise exception 'unperfect i_cnt_per_grp.';
  end if;
 
  if i_array_2d is null 
  then 
    return null;
  elsif i_dim_pin = 1
  then 
    return 
    (
      with 
      cte_slice_new_y_x as 
      (
        select 
          a_cur_new_z_old_y,
          sm_sc.fa_mx_concat_y(i_array_2d[a_cur_new_z_old_y : a_cur_new_z_old_y][a_cur_new_y_idx : a_cur_new_y_idx + i_cnt_per_grp - 1] order by a_cur_new_y_idx) as a_slice_new_y_x
        from generate_series(1, array_length(i_array_2d, 1)) tb_a_cur_new_z_old_y(a_cur_new_z_old_y)
          , generate_series(1, array_length(i_array_2d, 2), i_cnt_per_grp) tb_a_cur_new_y_idx(a_cur_new_y_idx)
        group by a_cur_new_z_old_y
      )
      select 
        array_agg(a_slice_new_y_x order by a_cur_new_z_old_y)
      from cte_slice_new_y_x
    );
  elsif i_dim_pin = 2
  then 
    return 
    (
      select 
        array_agg(i_array_2d[a_cur_old_y_new_z_idx : a_cur_old_y_new_z_idx + i_cnt_per_grp - 1][ : ] order by a_cur_old_y_new_z_idx)
      from generate_series(1, array_length(i_array_2d, 1), i_cnt_per_grp) tb_a_cur_old_y_new_z_idx(a_cur_old_y_new_z_idx)
    );
  end if;
end
$$
language plpgsql stable
parallel safe
cost 100;
-- -- set search_path to sm_sc;
-- select sm_sc.fv_mx_ele_2d_2_3d
--   (
--     array[[1,2,3,4,5,6,7,8,9,10,11,12],[21,22,23,24,25,26,27,28,29,30,31,32]]
--     , 3
--     , 1
--   );
-- select sm_sc.fv_mx_ele_2d_2_3d
--   (
--     array[[1,2],[3,4],[5,6],[7,8],[9,10],[11,12],[21,22],[23,24],[25,26],[27,28],[29,30],[31,32]]
--     , 3
--     , 2
--   );